#include "ServerInfo.h"
#include "../ProcessInfo.h"


string SystemInspector::loadavg()
{
    string loadavg;
    readFile("/proc/loadavg", 65536, &loadavg);
    return loadavg;
}

string overview(HttpRequest::Method, const Inspector::ArgList&)
{
    string result;
    result.reserve(1024);
    Timestamp now = Timestamp::now();
    result += "Page generated at ";
    result += now.toFormattedString();
    result += " (UTC)\n";
    {
    struct utsname un;
    if (::uname(&un) == 0)
    {
      stringPrintf(&result, "Hostname: %s\n", un.nodename);
      stringPrintf(&result, "Machine: %s\n", un.machine);
      stringPrintf(&result, "OS: %s %s %s\n", un.sysname, un.release, un.version);
    }
    }
    string stat;
    readFile("/proc/stat", 65536, &stat);
    Timestamp bootTime(Timestamp::kMicroSecondsPerSecond * getLong(stat, "btime "));
    result += "Boot time: ";
    result += bootTime.toFormattedString(false /* show microseconds */);
    result += " (UTC)\n";
    result += "Up time: ";
    result += uptime(now, bootTime, false /* show microseconds */);
    result += "\n";

    // CPU load
    {
    string loadavg;
    readFile("/proc/loadavg", 65536, &loadavg);
    stringPrintf(&result, "Processes created: %ld\n", getLong(stat, "processes "));
    stringPrintf(&result, "Loadavg: %s\n", loadavg.c_str());
    }

    // Memory
    {
    string meminfo;
    readFile("/proc/meminfo", 65536, &meminfo);
    long total_kb = getLong(meminfo, "MemTotal:");
    long free_kb = getLong(meminfo, "MemFree:");
    long buffers_kb = getLong(meminfo, "Buffers:");
    long cached_kb = getLong(meminfo, "Cached:");

    stringPrintf(&result, "Total Memory: %6ld MiB\n", total_kb / 1024);
    stringPrintf(&result, "Free Memory:  %6ld MiB\n", free_kb / 1024);
    stringPrintf(&result, "Buffers:      %6ld MiB\n", buffers_kb / 1024);
    stringPrintf(&result, "Cached:       %6ld MiB\n", cached_kb / 1024);
    stringPrintf(&result, "Real Used:    %6ld MiB\n", (total_kb - free_kb - buffers_kb - cached_kb) / 1024);
    stringPrintf(&result, "Real Free:    %6ld MiB\n", (free_kb + buffers_kb + cached_kb) / 1024);

    // Swap
    }
    // Disk
    // Network

    // ProcessInfo
    // string result;
    // result.reserve(1024);
    Timestamp now = Timestamp::now();
    result += "Page generated at ";
    result += now.toFormattedString();
    result += " (UTC)\nStarted at ";
    result += ProcessInfo::startTime().toFormattedString();
    result += " (UTC), up for ";
    result += uptime(now, ProcessInfo::startTime(), true/* show microseconds */);
    result += "\n";

    string procStatus = ProcessInfo::procStatus();
    result += getProcessName(procStatus);
    result += " (";
    result += ProcessInfo::exePath();
    result += ") running as ";
    result += "MyServer"; // username_;
    result += " on ";
    result += ProcessInfo::hostname();
    result += "\n";

    stringPrintf(&result, "pid %d, num of threads %ld, bits %zd\n",
                ProcessInfo::pid(), getLong(procStatus, "Threads:"), CHAR_BIT * sizeof(void*));

    result += "Virtual memory: ";
    stringPrintf(&result, "%.3f MiB, ",
                static_cast<double>(getLong(procStatus, "VmSize:")) / 1024.0);

    result += "RSS memory: ";
    stringPrintf(&result, "%.3f MiB\n",
                static_cast<double>(getLong(procStatus, "VmRSS:")) / 1024.0);

    stringPrintf(&result, "Opened files: %d, limit: %d\n",
                ProcessInfo::openedFiles(), ProcessInfo::maxOpenFiles());

    // string procStat = ProcessInfo::procStat();

    ProcessInfo::CpuTime t = ProcessInfo::cpuTime();
    stringPrintf(&result, "User time: %12.3fs\nSys time:  %12.3fs\n",
                t.userSeconds, t.systemSeconds);

    return result;

}